home *** CD-ROM | disk | FTP | other *** search
-
- /*********************************************************************
-
- FILENAME
- DPrintf.c
-
- DESCRIPTION
- This is the dprintf Macsbug dcmd for use with Exceptions.h.
-
- COPYRIGHT
- Copyright © Apple Computer, Inc. 1990-1991
- All rights reserved.
-
- ROUTINES
- EXTERNALS
- CommandEntry (dprintf)
- INTERNALS
- FormatFloat
- FormatLong
-
- MODIFICATION HISTORY
- 11/05/91 Sean Parent
- 1) Cleaned up for Develop article.
-
- *********************************************************************/
-
- /*********************************************************************
-
- INCLUDES
-
- *********************************************************************/
-
- #include <string.h>
- #include <stdio.h>
- #include <Types.h>
- #include <FixMath.h>
- #include "dcmd.h"
- #include "put.h"
-
- /*********************************************************************
-
- PROTOTYPES
-
- *********************************************************************/
-
- void FormatFloat(const char* format, short numArgs, long firstArg,
- long secondArg, float theFloat);
-
- void FormatLong(const char* format, short numArgs, long firstArg,
- long secondArg, long theLong);
-
- /*********************************************************************
-
- ROUTINE
- CommandEntry
-
- DESCRIPTION
- This is the implementation of the dprintf dcmd. See Exceptions.h
- for more information.
-
- *********************************************************************/
-
- pascal void CommandEntry(dcmdBlock* paramPtr)
- {
- switch (paramPtr->request) {
- case dcmdInit:
- break;
- case dcmdDoIt:
- {
- char format[256];
- size_t formatSize;
- short i, j, numArgs;
- long firstArg, secondArg;
- short* shortWalker;
- Fixed* fixedWalker;
- char* nextp;
- char* convChar;
- char* stackPtr =
- (char*)paramPtr->registerFile[A7Register];
- unsigned char* formatWalker = *((char**)stackPtr)++;
-
- dcmdSwapWorlds(); /* not necessary */
-
- /* start scanning until end of format string */
-
- while (*formatWalker != '\0') {
-
- /*
- Find the next format spec (i.e. %d) and print out
- anything before it.
- */
-
- nextp = strchr(formatWalker, '%');
- if (nextp == nil)
- nextp = formatWalker + strlen(formatWalker);
-
- PutBytesTo(formatWalker, nextp - formatWalker, 0);
- formatWalker = nextp;
-
- if (*formatWalker == '\0') break;
-
- /*
- Find the length of the format spec (skip initial % and
- include the convertion char)
- */
-
- formatSize = strcspn(formatWalker + 1,
- "bcdeEfFgGijJMopPrRsTuxX%") + 2;
-
- /* Make a copy of the format spec. */
-
- memcpy(format, formatWalker, formatSize);
- format[formatSize] = (char)'\0';
-
- /*
- If the spec contains "*" in place of field width or
- precision then get the width and/or precision from
- the stack.
- */
-
- i = (short)(strcspn(format, "*") + 1);
- if (i < formatSize) {
- firstArg = *((long*)stackPtr)++;
-
- j = (short)(strcspn(format + i, "*") + i + 1);
- if (j < formatSize) {
- secondArg = *((long*)stackPtr)++;
- numArgs = 2;
- } else numArgs = 1;
- } else numArgs = 0;
-
- formatWalker += formatSize; /* increment the format p */
-
- /*
- Get address of conversion character. Address is used
- so it can be changed directly in the format spec.
- */
-
- convChar = &format[formatSize - 1];
-
- /*
- If the conversion character requires special treatment
- then fix it up here. Otherwise do the standard
- formatting.
- */
-
- switch (*convChar) {
- case 'b': /* boolean */
- if (*((long*)stackPtr)++) PutCStr("true");
- else PutCStr("false");
- break;
- case 'j': /* Point */
- *convChar = 'd';
-
- for (i = 1; i >= 0; --i) {
- FormatLong(format, numArgs, firstArg, secondArg,
- *((short*)stackPtr)++);
- if (i != 0) PutCStr(", ");
- }
- break;
- case 'J': /* point* */
- *convChar = 'f';
-
- fixedWalker = *((Fixed**)stackPtr)++;
-
- for (i = 1; i >= 0; --i) {
- FormatFloat(format, numArgs, firstArg, secondArg,
- (float)*fixedWalker++ / 0x00010000);
-
- if (i != 0) PutCStr(", ");
- }
- break;
- case 'T': /* Fract */
- *convChar = 'f';
-
- FormatFloat(format, numArgs, firstArg, secondArg,
- (float)(*((Fract*)stackPtr)++) / 0x40000000);
-
- break;
- case 'M': /* mapping */
- *convChar = 'f';
-
- fixedWalker = *((Fixed**)stackPtr)++;
-
- for (j = 2; j >= 0; --j) {
- for (i = 1; i >= 0; --i) {
- FormatFloat(format, numArgs, firstArg, secondArg,
- (float)*fixedWalker++ / 0x00010000);
-
- PutCStr(", ");
- }
- FormatFloat(format, numArgs, firstArg, secondArg,
- (float)(*(Fract*)fixedWalker++) / 0x40000000);
-
- if (j != 0) PutCStr("\n");
- }
- break;
-
- case 'r': /* Rect* */
- *convChar = 'd';
-
- shortWalker = *((short**)stackPtr)++;
-
- for (i = 3; i >= 0; --i) {
- FormatLong(format, numArgs, firstArg, secondArg,
- *shortWalker++);
-
- if (i != 0) PutCStr(", ");
- }
- break;
- case 'R': /* rectangle* */
- *convChar = 'f';
-
- fixedWalker = *((Fixed**)stackPtr)++;
-
- for (i = 3; i >= 0; --i) {
- FormatFloat(format, numArgs, firstArg, secondArg,
- (float)*fixedWalker++ / 0x00010000);
-
- if (i != 0) PutCStr(", ");
- }
- break;
- case 'F': /* Fixed */
- *convChar = 'f';
-
- FormatFloat(format, numArgs, firstArg, secondArg,
- (float)(*((Fixed*)stackPtr)++) / 0x00010000);
-
- break;
- case 'f':
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- FormatFloat(format, numArgs, firstArg, secondArg,
- *((extended*)stackPtr)++);
- break;
- default:
- FormatLong(format, numArgs, firstArg, secondArg,
- *((long*)stackPtr)++);
- break;
- }
- }
- PutLine();
-
- dcmdSwapWorlds();
- }
- break;
- case dcmdHelp:
- dcmdDrawLine(
- "\pdprintf");
- dcmdDrawLine(
- "\p dprintf is used to display information from a C");
- dcmdDrawLine(
- "\p application. See Exceptions.h for more information.");
- break;
- default:
- dcmdDrawLine("\punknown request");
- break;
- }
- }; /* CommandEntry */
-
- /*********************************************************************
-
- ROUTINE
- FormatFloat
-
- DESCRIPTION
- This will format a float according to the format string.
-
- *********************************************************************/
-
- void FormatFloat(const char* format, short numArgs, long firstArg,
- long secondArg, float theFloat)
- {
- char final[256];
-
- switch (numArgs) {
- case 0:
- sprintf(final, format, theFloat);
- break;
- case 1:
- sprintf(final, format, firstArg, theFloat);
- break;
- case 2:
- sprintf(final, format, firstArg, secondArg, theFloat);
- break;
- }
- PutCStr(final);
- } /* FormatFloat */
-
- /*********************************************************************
-
- ROUTINE
- FormatFloat
-
- DESCRIPTION
- This will format a long according to the format string.
-
- *********************************************************************/
-
- void FormatLong(const char* format, short numArgs, long firstArg,
- long secondArg, long theLong)
- {
- char final[256];
-
- switch (numArgs) {
- case 0:
- sprintf(final, format, theLong);
- break;
- case 1:
- sprintf(final, format, firstArg, theLong);
- break;
- case 2:
- sprintf(final, format, firstArg, secondArg, theLong);
- break;
- }
- PutCStr(final);
- } /* FormatLong */
-
- /*********************************************************************
-
- STUBS
-
- DESCRIPTION
- The following are stubs to override the C library routines so that
- the dcmd isn’t so big. Neither will ever be called by sprintf.
-
- *********************************************************************/
-
- size_t fwrite (const void *, size_t, size_t, FILE *) { return(0); }
- _flsbuf() {}
-
-